﻿namespace MsForgeReboot.Services.Tests.Fakes {
    #region Usings

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Data.Entity;
    using System.Linq;
    using System.Linq.Expressions;

    #endregion

    public class InMemoryDbSet<T> : IDbSet<T>
        where T : class, new() {
        private readonly HashSet<T> set;

        private readonly IQueryable<T> queryableSet;

        public InMemoryDbSet()
            : this(Enumerable.Empty<T>()) {}

        public InMemoryDbSet(IEnumerable<T> entities) {
            this.set = new HashSet<T>();

            foreach (var entity in entities) {
                this.set.Add(entity);
            }

            this.queryableSet = this.set.AsQueryable();
        }

        public T Add(T entity) {
            this.set.Add(entity);
            return entity;
        }

        public T Attach(T entity) {
            this.set.Add(entity);
            return entity;
        }

        public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T {
            throw new NotImplementedException();
        }

        public T Create() {
            return new T();
        }

        public T Find(params object[] keyValues) {
            throw new NotImplementedException();
        }

        public ObservableCollection<T> Local {
            get {
                throw new NotImplementedException();
            }
        }

        public T Remove(T entity) {
            this.set.Remove(entity);
            return entity;
        }

        public IEnumerator<T> GetEnumerator() {
            return this.set.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator() {
            return this.GetEnumerator();
        }

        public Type ElementType {
            get {
                return this.queryableSet.ElementType;
            }
        }

        public Expression Expression {
            get {
                return this.queryableSet.Expression;
            }
        }

        public IQueryProvider Provider {
            get {
                return this.queryableSet.Provider;
            }
        }
    }
}
